Add a function gdk_window_invalidate_maybe_recurse() for use in "shallow
authorOwen Taylor <otaylor@redhat.com>
Sun, 4 Nov 2001 22:57:03 +0000 (22:57 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Sun, 4 Nov 2001 22:57:03 +0000 (22:57 +0000)
Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>

        * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse()
        for use in "shallow invalidation" of a widget. (Windows belonging
        to the widget, but not to the widget's children)

        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
        flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
        up on ancestors up to the resize container on queue_resize. Size
        requests only actually take place if GTK_REQUEST_NEEDED, size
        allocations only take place if GTK_ALLOC_NEEDED or the size
        changed.

        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
        container->resize_widgets and the RESIZE_NEEDED flag since the
        above flags are sufficient to figure out what needs to be
        resized/reallocated. Remove code manipulating
        container->resize_widget.

        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
        allows widgets to turn off being automatically invalidated is when
        they are resized.

        * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
        a widget is resized or moved is "shallow" as described above -
        only the windows that need to be invalidated are invalidated.

        * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt:
        Make these widget's init functions call
        gtk_widget_set_redraw_on_allocate(widget,FALSE).

        * gtk/gtkwindow.c (gtk_window_configure_event): Call
        _gtk_container_queue_resize(), since we don't want
        redrawing. (Probably could be done for other
        calls to gtk_widget_queue_resize() in gtkwindow.c,
        but this is the most important one.)

        * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
        gtk_widget_queue_draw() - size_allocate() handles
        that as appropriate.

        * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
        of queue_clear() to avoid invalidating children.

22 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/Changes-2.0.txt
docs/reference/gtk/tmpl/gtkimcontext.sgml
gdk/gdkwindow.c
gdk/gdkwindow.h
gtk/gtkalignment.c
gtk/gtkbox.c
gtk/gtkcontainer.c
gtk/gtkcontainer.h
gtk/gtkframe.c
gtk/gtkprivate.h
gtk/gtksizegroup.c
gtk/gtktable.c
gtk/gtkwidget.c
gtk/gtkwidget.h
gtk/gtkwindow.c

index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index ec47b7bbb40d37e82e69ec4d239db62f3f68abcb..620483d825e1844dd9ff554ffd9c3396ed444111 100644 (file)
@@ -1,3 +1,47 @@
+Sun Nov  4 16:02:08 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.[ch]: Add a function gdk_window_invalidate_maybe_recurse() 
+       for use in "shallow invalidation" of a widget. (Windows belonging
+       to the widget, but not to the widget's children)
+
+        * gtk/gtkprivate.h gtk/gtkwidget.c gtk/gtksizegroup.c: Add private
+       flags GTK_ALLOC_NEEDED, GTK_REQUEST_NEEDED.  These flags are set
+       up on ancestors up to the resize container on queue_resize. Size
+       requests only actually take place if GTK_REQUEST_NEEDED, size
+       allocations only take place if GTK_ALLOC_NEEDED or the size
+       changed.
+
+        * gtk/gtkcontainer.c gtk/gtkwidget.c: Remove
+       container->resize_widgets and the RESIZE_NEEDED flag since the
+       above flags are sufficient to figure out what needs to be
+       resized/reallocated. Remove code manipulating
+       container->resize_widget.
+
+        * gtk/gtkwidget.[ch]: Add gtk_widget_set_redraw_on_alloc(); this
+       allows widgets to turn off being automatically invalidated is when
+       they are resized.
+
+       * gtk/gtkwidget.[ch] (gtk_widget_size_allocate): Invalidation when
+       a widget is resized or moved is "shallow" as described above -
+       only the windows that need to be invalidated are invalidated.
+
+       * gtk/gtkbox.c gtk/gtktable.c gtk/gtkalignment.c docs/Changes-2.0.txt: 
+       Make these widget's init functions call 
+       gtk_widget_set_redraw_on_allocate(widget,FALSE).
+
+       * gtk/gtkwindow.c (gtk_window_configure_event): Call 
+       _gtk_container_queue_resize(), since we don't want
+       redrawing. (Probably could be done for other 
+       calls to gtk_widget_queue_resize() in gtkwindow.c,
+       but this is the most important one.)
+
+       * gtk/gtkwindow.c (gtk_window_move_resize): Don't call
+       gtk_widget_queue_draw() - size_allocate() handles
+       that as appropriate.
+
+       * gtk/gtkframe.c (gtk_frame_size_allocate): Invalidate instead
+       of queue_clear() to avoid invalidating children.
+
 2001-11-04  jacob berkman  <jacob@ximian.com>
 
        * gtk/gtkmain.c (find_module): don't free the module name until
index efe9dc5e8c146134619e989b13d748a6b7f57701..a5953d523564766d6801bd53c6dbdff09b5cefaf 100644 (file)
@@ -508,3 +508,9 @@ Incompatible Changes from GTK+-1.2 to GTK+-2.0:
   are deprecated, as GdkRgb works on any colormap and visual.  You no
   longer need to gtk_widget_push_cmap (gtk_preview_get_cmap ()) in
   your code.
+
+* The GtkBox, GtkTable, and GtkAlignment widgets now call
+  gtk_widget_set_redraw_on_allocate (widget, FALSE); on themselves.
+  If you want to actually draw contents in a widget derived from
+  one of these widgets, you'll probably want to change this
+  in your init() function.
index 74f19bb38faf84cef9b7aef86294ef94a951e9fd..36a2a280735d4543feb5b7d030451e20b98ddc36 100644 (file)
@@ -100,6 +100,16 @@ GtkIMContext
 @imcontext: the object which received the signal.
 @arg1: 
 
+<!-- ##### SIGNAL GtkIMContext::delete-surrounding ##### -->
+<para>
+
+</para>
+
+@imcontext: the object which received the signal.
+@arg1: 
+@arg2: 
+@Returns: 
+
 <!-- ##### SIGNAL GtkIMContext::preedit-changed ##### -->
 <para>
 
@@ -121,3 +131,11 @@ GtkIMContext
 
 @imcontext: the object which received the signal.
 
+<!-- ##### SIGNAL GtkIMContext::retrieve-surrounding ##### -->
+<para>
+
+</para>
+
+@imcontext: the object which received the signal.
+@Returns: 
+
index b8729093d0cb6484a67a90382b9de335e8ce3a58..e171edc2fa4a1f5eef6e981b23d43e0a6cd33eaf 100644 (file)
@@ -2152,10 +2152,12 @@ gdk_window_invalidate_rect   (GdkWindow    *window,
 }
 
 /**
- * gdk_window_invalidate_region:
+ * gdk_window_invalidate_maybe_recurse:
  * @window: a #GdkWindow
  * @region: a #GdkRegion
- * @invalidate_children: %TRUE to also invalidate child windows 
+ * @child_func: function to use to decide if to recurse to a child,
+ *              %NULL means never recurse.
+ * @child_func_data: data passed to @child_func
  *
  * Adds @region to the update area for @window. The update area is the
  * region that needs to be redrawn, or "dirty region." The call
@@ -2169,16 +2171,16 @@ gdk_window_invalidate_rect   (GdkWindow    *window,
  * normally there's no need to do that manually, you just need to
  * invalidate regions that you know should be redrawn.
  *
- * The @invalidate_children parameter controls whether the region of
+ * The @child_func parameter controls whether the region of
  * each child window that intersects @region will also be invalidated.
- * If %FALSE, then the update area for child windows will remain
- * unaffected.
- *
+ * Only children for whic @child_func returns TRUE will have the area
+ * invalidated.
  **/
 void
-gdk_window_invalidate_region (GdkWindow *window,
-                             GdkRegion *region,
-                             gboolean   invalidate_children)
+gdk_window_invalidate_maybe_recurse (GdkWindow *window,
+                                    GdkRegion *region,
+                                    gboolean (*child_func) (GdkWindow *, gpointer),
+                                    gpointer   user_data)
 {
   GdkWindowObject *private = (GdkWindowObject *)window;
   GdkRegion *visible_region;
@@ -2233,7 +2235,7 @@ gdk_window_invalidate_region (GdkWindow *window,
                                           gdk_window_update_idle, NULL, NULL);
        }
       
-      if (invalidate_children)
+      if (child_func)
        {
          GList *tmp_list;
          
@@ -2242,8 +2244,8 @@ gdk_window_invalidate_region (GdkWindow *window,
            {
              GdkWindowObject *child = tmp_list->data;
              tmp_list = tmp_list->next;
-             
-             if (!child->input_only)
+
+             if (!child->input_only && (*child_func) ((GdkWindow *)child, user_data))
                {
                  GdkRegion *child_region;
                  gint x, y;
@@ -2265,6 +2267,48 @@ gdk_window_invalidate_region (GdkWindow *window,
   gdk_region_destroy (visible_region);
 }
 
+static gboolean
+true_predicate (GdkWindow *window,
+               gpointer   user_data)
+{
+  return TRUE;
+}
+
+/**
+ * gdk_window_invalidate_region:
+ * @window: a #GdkWindow
+ * @region: a #GdkRegion
+ * @invalidate_children: %TRUE to also invalidate child windows 
+ *
+ * Adds @region to the update area for @window. The update area is the
+ * region that needs to be redrawn, or "dirty region." The call
+ * gdk_window_process_updates() sends one or more expose events to the
+ * window, which together cover the entire update area. An
+ * application would normally redraw the contents of @window in
+ * response to those expose events.
+ *
+ * GDK will call gdk_window_process_all_updates() on your behalf
+ * whenever your program returns to the main loop and becomes idle, so
+ * normally there's no need to do that manually, you just need to
+ * invalidate regions that you know should be redrawn.
+ *
+ * The @invalidate_children parameter controls whether the region of
+ * each child window that intersects @region will also be invalidated.
+ * If %FALSE, then the update area for child windows will remain
+ * unaffected. See gdk_window_invalidate_maybe_recurse if you need
+ * fine grained control over which children are invalidated.
+ **/
+void
+gdk_window_invalidate_region (GdkWindow *window,
+                             GdkRegion *region,
+                             gboolean   invalidate_children)
+{
+  gdk_window_invalidate_maybe_recurse (window, region,
+                                      invalidate_children ?
+                                        true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
+                                      NULL);
+}
+
 /**
  * gdk_window_get_update_area:
  * @window: a #GdkWindow
index e4d0138fd37b0073140bfd4358fe3843ca6cdf7b..bca2b065d3f9d346d9ed812b8b6e07160ec12e4a 100644 (file)
@@ -491,12 +491,16 @@ void gdk_window_begin_move_drag   (GdkWindow     *window,
                                    guint32        timestamp);
 
 /* Interface for dirty-region queueing */
-void       gdk_window_invalidate_rect     (GdkWindow    *window,
-                                          GdkRectangle *rect,
-                                          gboolean      invalidate_children);
-void       gdk_window_invalidate_region   (GdkWindow    *window,
-                                          GdkRegion    *region,
-                                          gboolean      invalidate_children);
+void       gdk_window_invalidate_rect           (GdkWindow    *window,
+                                                GdkRectangle *rect,
+                                                gboolean      invalidate_children);
+void       gdk_window_invalidate_region         (GdkWindow    *window,
+                                                GdkRegion    *region,
+                                                gboolean      invalidate_children);
+void       gdk_window_invalidate_maybe_recurse  (GdkWindow *window,
+                                                GdkRegion *region,
+                                                gboolean (*child_func) (GdkWindow *, gpointer),
+                                                gpointer   user_data);
 GdkRegion *gdk_window_get_update_area     (GdkWindow    *window);
 
 void       gdk_window_freeze_updates      (GdkWindow    *window);
index 5db7589c72b216fb0dd68b99eedde26ed25613ab..9c33fd3077201aaa5501a2ef7b6fd1961f3a3feb 100644 (file)
@@ -139,6 +139,7 @@ static void
 gtk_alignment_init (GtkAlignment *alignment)
 {
   GTK_WIDGET_SET_FLAGS (alignment, GTK_NO_WINDOW);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (alignment), FALSE);
 
   alignment->xalign = 0.5;
   alignment->yalign = 0.5;
index add75ec91ddfb76d54a890cc09703e6015fc7169..4c50b1137ff7016bd00ca4c2b027f449bd30d260 100644 (file)
@@ -168,7 +168,8 @@ static void
 gtk_box_init (GtkBox *box)
 {
   GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
-
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (box), FALSE);
+  
   box->children = NULL;
   box->spacing = 0;
   box->homogeneous = FALSE;
index c25802253b74bb24642a235f1d4a868712a45c05..a6b553da28da8497e035aac60a7564246cff494c 100644 (file)
@@ -698,7 +698,6 @@ gtk_container_init (GtkContainer *container)
   container->need_resize = FALSE;
   container->resize_mode = GTK_RESIZE_PARENT;
   container->reallocate_redraws = FALSE;
-  container->resize_widgets = NULL;
 }
 
 static void
@@ -713,8 +712,6 @@ gtk_container_destroy (GtkObject *object)
   
   if (GTK_CONTAINER_RESIZE_PENDING (container))
     _gtk_container_dequeue_resize_handler (container);
-  if (container->resize_widgets)
-    _gtk_container_clear_resize_widgets (container);
 
   /* do this before walking child widgets, to avoid
    * removing children from focus chain one by one.
@@ -899,28 +896,6 @@ _gtk_container_dequeue_resize_handler (GtkContainer *container)
   GTK_PRIVATE_UNSET_FLAG (container, GTK_RESIZE_PENDING);
 }
 
-void
-_gtk_container_clear_resize_widgets (GtkContainer *container)
-{
-  GSList *node;
-
-  g_return_if_fail (container != NULL);
-  g_return_if_fail (GTK_IS_CONTAINER (container));
-
-  node = container->resize_widgets;
-
-  while (node)
-    {
-      GtkWidget *widget = node->data;
-
-      GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-      node = node->next;
-    }
-  
-  g_slist_free (container->resize_widgets);
-  container->resize_widgets = NULL;
-}
-
 void
 gtk_container_set_resize_mode (GtkContainer  *container,
                               GtkResizeMode  resize_mode)
@@ -940,14 +915,8 @@ gtk_container_set_resize_mode (GtkContainer  *container,
     {
       container->resize_mode = resize_mode;
       
-      if (resize_mode == GTK_RESIZE_IMMEDIATE)
-       gtk_container_check_resize (container);
-      else
-       {
-         _gtk_container_clear_resize_widgets (container);
-         gtk_widget_queue_resize (GTK_WIDGET (container));
-       }
-       g_object_notify (G_OBJECT (container), "resize_mode");
+      gtk_widget_queue_resize (GTK_WIDGET (container));
+      g_object_notify (G_OBJECT (container), "resize_mode");
     }
 }
 
@@ -987,7 +956,7 @@ gtk_container_get_resize_container (GtkContainer *container)
   while (widget->parent)
     {
       widget = widget->parent;
-      if (GTK_IS_RESIZE_CONTAINER (widget) && !GTK_WIDGET_RESIZE_NEEDED (widget))
+      if (GTK_IS_RESIZE_CONTAINER (widget))
        break;
     }
 
@@ -997,32 +966,52 @@ gtk_container_get_resize_container (GtkContainer *container)
 static gboolean
 gtk_container_idle_sizer (gpointer data)
 {
+  static gboolean initialized = 0;
+  static GTimeVal last_time;
+  GTimeVal current_time;
+  
   GDK_THREADS_ENTER ();
 
-  /* we may be invoked with a container_resize_queue of NULL, because
-   * queue_resize could have been adding an extra idle function while
-   * the queue still got processed. we better just ignore such case
-   * than trying to explicitely work around them with some extra flags,
-   * since it doesn't cause any actual harm.
-   */
-  while (container_resize_queue)
+  if (container_resize_queue)
     {
-      GSList *slist;
-      GtkWidget *widget;
-
-      slist = container_resize_queue;
-      container_resize_queue = slist->next;
-      widget = slist->data;
-      g_slist_free_1 (slist);
-
-      GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_PENDING);
-      gtk_container_check_resize (GTK_CONTAINER (widget));
+      /* we may be invoked with a container_resize_queue of NULL, because
+       * queue_resize could have been adding an extra idle function while
+       * the queue still got processed. we better just ignore such case
+       * than trying to explicitely work around them with some extra flags,
+       * since it doesn't cause any actual harm.
+       */
+      while (container_resize_queue)
+       {
+         GSList *slist;
+         GtkWidget *widget;
+         
+         slist = container_resize_queue;
+         container_resize_queue = slist->next;
+         widget = slist->data;
+         g_slist_free_1 (slist);
+         
+         GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_PENDING);
+         gtk_container_check_resize (GTK_CONTAINER (widget));
+       }
+      
+      gdk_window_process_all_updates ();
+      
+      g_get_current_time (&current_time);
+      
+      if (initialized)
+       {
+         gdouble diff = ((current_time.tv_usec - last_time.tv_usec) / 1000. +
+                         (current_time.tv_sec - last_time.tv_sec) * 1000.);
+         /*      g_print ("Frame time: %g msec\n", diff);           */
+       }
+      else
+       initialized = TRUE;
+      
+      last_time = current_time;
+      
+      GDK_THREADS_LEAVE ();
     }
 
-  gdk_window_process_all_updates ();
-
-  GDK_THREADS_LEAVE ();
-
   return FALSE;
 }
 
@@ -1034,21 +1023,22 @@ _gtk_container_queue_resize (GtkContainer *container)
   g_return_if_fail (container != NULL);
   g_return_if_fail (GTK_IS_CONTAINER (container));
 
-  /* clear resize widgets for resize containers
-   * before aborting prematurely. this is especially
-   * important for toplevels which may need imemdiate
-   * processing or their resize handler to be queued.
-   */
-  if (GTK_IS_RESIZE_CONTAINER (container))
-    _gtk_container_clear_resize_widgets (container);
-  if (GTK_OBJECT_DESTROYED (container) ||
-      GTK_WIDGET_RESIZE_NEEDED (container))
-    return;
-  
   resize_container = gtk_container_get_resize_container (container);
   
   if (resize_container)
     {
+      GtkWidget *widget = GTK_WIDGET (container);
+      
+      while (!GTK_WIDGET_ALLOC_NEEDED (widget) || !GTK_WIDGET_REQUEST_NEEDED (widget))
+       {
+         GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
+         GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
+         if (widget == GTK_WIDGET (resize_container))
+           break;
+         
+         widget = widget->parent;
+       }
+      
       if (GTK_WIDGET_VISIBLE (resize_container) &&
          (GTK_WIDGET_TOPLEVEL (resize_container) || GTK_WIDGET_DRAWABLE (resize_container)))
        {
@@ -1064,16 +1054,9 @@ _gtk_container_queue_resize (GtkContainer *container)
                                           NULL);
                  container_resize_queue = g_slist_prepend (container_resize_queue, resize_container);
                }
-             
-             GTK_PRIVATE_SET_FLAG (container, GTK_RESIZE_NEEDED);
-             resize_container->resize_widgets =
-               g_slist_prepend (resize_container->resize_widgets, container);
              break;
 
            case GTK_RESIZE_IMMEDIATE:
-             GTK_PRIVATE_SET_FLAG (container, GTK_RESIZE_NEEDED);
-             resize_container->resize_widgets =
-               g_slist_prepend (resize_container->resize_widgets, container);
              gtk_container_check_resize (resize_container);
              break;
 
@@ -1134,135 +1117,24 @@ gtk_container_real_check_resize (GtkContainer *container)
  *  queued a resize request. Which means that the allocation
  *  is not sufficient for the requisition of some child.
  *  We've already performed a size request at this point,
- *  so we simply need to run through the list of resize
- *  widgets and reallocate their sizes appropriately. We
- *  make the optimization of not performing reallocation
- *  for a widget who also has a parent in the resize widgets
- *  list. GTK_RESIZE_NEEDED is used for flagging those
- *  parents inside this function.
+ *  so we simply need to reallocate and let the allocation
+ *  trickle down via GTK_WIDGET_ALLOC_NEEDED flags. 
  */
 void
 gtk_container_resize_children (GtkContainer *container)
 {
   GtkWidget *widget;
-  GtkWidget *resize_container;
-  GSList *resize_widgets;
-  GSList *resize_containers;
-  GSList *node;
   
   /* resizing invariants:
    * toplevels have *always* resize_mode != GTK_RESIZE_PARENT set.
-   * containers with resize_mode==GTK_RESIZE_PARENT have to have resize_widgets
-   * set to NULL.
-   * containers that are flagged RESIZE_NEEDED must have resize_widgets set to
-   * NULL, or are toplevels (thus have ->parent set to NULL).
-   * widgets that are in some container->resize_widgets list must be flagged with
-   * RESIZE_NEEDED.
-   * widgets that have RESIZE_NEEDED set must be referenced in some
-   * GTK_IS_RESIZE_CONTAINER (container)->resize_widgets list.
    * containers that have an idle sizer pending must be flagged with
    * RESIZE_PENDING.
    */
-  
   g_return_if_fail (container != NULL);
   g_return_if_fail (GTK_IS_CONTAINER (container));
 
-  /* we first check out if we actually need to perform a resize,
-   * which is not the case if we got another container queued for
-   * a resize in our ancestry. also we can skip the whole
-   * resize_widgets checks if we are a toplevel and NEED_RESIZE.
-   * this code assumes that our allocation is sufficient for our
-   * requisition, since otherwise we would NEED_RESIZE.
-   */
-  resize_container = GTK_WIDGET (container);
-  while (resize_container)
-    {
-      if (GTK_WIDGET_RESIZE_NEEDED (resize_container))
-       break;
-      resize_container = resize_container->parent;
-    }
-  if (resize_container)
-    {
-      /* queue_resize and size_allocate both clear our
-       * resize_widgets list.
-       */
-      if (resize_container->parent)
-       _gtk_container_queue_resize (container);
-      else
-       gtk_widget_size_allocate (GTK_WIDGET (container),
-                                 &GTK_WIDGET (container)->allocation);
-      return;
-    }
-
-  resize_container = GTK_WIDGET (container);
-
-  /* we now walk the ancestry for all resize widgets as long
-   * as they are our children and as long as their allocation
-   * is insufficient, since we don't need to reallocate below that.
-   */
-  resize_widgets = container->resize_widgets;
-  container->resize_widgets = NULL;
-  for (node = resize_widgets; node; node = node->next)
-    {
-      widget = node->data;
-
-      GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-
-      while (widget->parent != resize_container &&
-            ((widget->allocation.width < widget->requisition.width) ||
-             (widget->allocation.height < widget->requisition.height)))
-       widget = widget->parent;
-      
-      GTK_PRIVATE_SET_FLAG (widget, GTK_RESIZE_NEEDED);
-      node->data = widget;
-    }
-
-  /* for the newly setup resize_widgets list, we now walk each widget's
-   * ancestry to sort those widgets out that have RESIZE_NEEDED parents.
-   * we can safely stop the walk if we are the parent, since we checked
-   * our own ancestry already.
-   */
-  resize_containers = NULL;
-  for (node = resize_widgets; node; node = node->next)
-    {
-      GtkWidget *parent;
-
-      widget = node->data;
-      
-      if (!GTK_WIDGET_RESIZE_NEEDED (widget))
-       continue;
-      
-      parent = widget->parent;
-      
-      while (parent != resize_container)
-       {
-         if (GTK_WIDGET_RESIZE_NEEDED (parent))
-           {
-             GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-             widget = parent;
-           }
-         parent = parent->parent;
-       }
-      
-      if (!g_slist_find (resize_containers, widget))
-       {
-         resize_containers = g_slist_prepend (resize_containers, widget);
-         gtk_widget_ref (widget);
-       }
-    }
-  g_slist_free (resize_widgets);
-  
-  for (node = resize_containers; node; node = node->next)
-    {
-      widget = node->data;
-      
-      GTK_PRIVATE_UNSET_FLAG (widget, GTK_RESIZE_NEEDED);
-
-      gtk_widget_size_allocate (widget, &widget->allocation);
-
-      gtk_widget_unref (widget);
-    }
-  g_slist_free (resize_containers);
+  widget = GTK_WIDGET (container);
+  gtk_widget_size_allocate (widget, &widget->allocation);
 }
 
 /**
@@ -1630,8 +1502,6 @@ get_allocation_coords (GtkContainer  *container,
                       GtkWidget     *widget,
                       GdkRectangle  *allocation)
 {
-  GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-
   *allocation = widget->allocation;
 
   return gtk_widget_translate_coordinates (widget, GTK_WIDGET (container),
index 98f7be851dbc8461f1b0f84feecd3fc732405e54..ae8095aee231b878717d6d8f4715636f94173cf5 100644 (file)
@@ -63,10 +63,6 @@ struct _GtkContainer
   guint resize_mode : 2;
   guint reallocate_redraws : 1;
   guint has_focus_chain : 1;
-  
-  /* The list of children that requested a resize
-   */
-  GSList *resize_widgets;
 };
 
 struct _GtkContainerClass
index 7efc069a522b5e700e5675b417189580c82333ee..95287ae2dd4df4a2be7ed7840667de6fcf82b2f2 100644 (file)
@@ -613,7 +613,7 @@ gtk_frame_size_allocate (GtkWidget     *widget,
        new_allocation.y != frame->child_allocation.y ||
        new_allocation.width != frame->child_allocation.width ||
        new_allocation.height != frame->child_allocation.height))
-    gtk_widget_queue_clear (widget);
+    gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
   
   if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
     gtk_widget_size_allocate (bin->child, &new_allocation);
index 0de6707cf7e3e667cd40a5a762b3297c038fca18..86935ee1bb18fcb36a9ed1766122d42bc985d3d1 100644 (file)
@@ -43,14 +43,16 @@ typedef enum
 {
   PRIVATE_GTK_USER_STYLE       = 1 <<  0,
   PRIVATE_GTK_RESIZE_PENDING   = 1 <<  2,
-  PRIVATE_GTK_RESIZE_NEEDED    = 1 <<  3,
   PRIVATE_GTK_LEAVE_PENDING    = 1 <<  4,
   PRIVATE_GTK_HAS_SHAPE_MASK   = 1 <<  5,
   PRIVATE_GTK_IN_REPARENT       = 1 <<  6,
   PRIVATE_GTK_DIRECTION_SET     = 1 <<  7,   /* If the reading direction is not DIR_NONE */
   PRIVATE_GTK_DIRECTION_LTR     = 1 <<  8,   /* If the reading direction is DIR_LTR */
   PRIVATE_GTK_ANCHORED          = 1 <<  9,   /* If widget has a GtkWindow ancestor */
-  PRIVATE_GTK_CHILD_VISIBLE     = 1 <<  10   /* If widget should be mapped when parent is mapped */
+  PRIVATE_GTK_CHILD_VISIBLE     = 1 <<  10,  /* If widget should be mapped when parent is mapped */
+  PRIVATE_GTK_REDRAW_ON_ALLOC   = 1 <<  11,  /* If we should queue a draw on the entire widget when it is reallocated */
+  PRIVATE_GTK_ALLOC_NEEDED      = 1 <<  12,  /* If we we should allocate even if the allocation is the same */
+  PRIVATE_GTK_REQUEST_NEEDED    = 1 <<  13   /* Whether we need to call gtk_widget_size_request */
 } GtkPrivateFlags;
 
 /* Macros for extracting a widgets private_flags from GtkWidget.
@@ -58,7 +60,6 @@ typedef enum
 #define GTK_PRIVATE_FLAGS(wid)            (GTK_WIDGET (wid)->private_flags)
 #define GTK_WIDGET_USER_STYLE(obj)       ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0)
 #define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0)
-#define GTK_WIDGET_RESIZE_NEEDED(obj)    ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_NEEDED) != 0)
 #define GTK_WIDGET_LEAVE_PENDING(obj)    ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_LEAVE_PENDING) != 0)
 #define GTK_WIDGET_HAS_SHAPE_MASK(obj)   ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0)
 #define GTK_WIDGET_IN_REPARENT(obj)      ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0)
@@ -66,6 +67,9 @@ typedef enum
 #define GTK_WIDGET_DIRECTION_LTR(obj)     ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0)
 #define GTK_WIDGET_ANCHORED(obj)          ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0)
 #define GTK_WIDGET_CHILD_VISIBLE(obj)     ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0)
+#define GTK_WIDGET_REDRAW_ON_ALLOC(obj)   ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0)
+#define GTK_WIDGET_ALLOC_NEEDED(obj)      ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0)
+#define GTK_WIDGET_REQUEST_NEEDED(obj)    ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0)
 
 /* Macros for setting and clearing private widget flags.
  * we use a preprocessor string concatenation here for a clear
index 3116183ae42c9e1a2c616ee43c527727fdb67b1c..2ceca3c4d8a148afa24100f5f1db1d3644e8cb19 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "gtkcontainer.h"
 #include "gtkintl.h"
+#include "gtkprivate.h"
 #include "gtksignal.h"
 #include "gtksizegroup.h"
 
@@ -116,8 +117,8 @@ add_widget_to_closure (GtkWidget       *widget,
 static void
 real_queue_resize (GtkWidget *widget)
 {
-  if (GTK_IS_RESIZE_CONTAINER (widget))
-    _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
+  GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED);
+  GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED);
   
   if (widget->parent)
     _gtk_container_queue_resize (GTK_CONTAINER (widget->parent));
@@ -476,12 +477,23 @@ get_base_dimension (GtkWidget        *widget,
     }
 }
 
+static void
+do_size_request (GtkWidget *widget)
+{
+  if (GTK_WIDGET_REQUEST_NEEDED (widget))
+    {
+      gtk_widget_ensure_style (widget);
+      gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
+      
+      GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED);
+    }
+}
+
 static gint
 compute_base_dimension (GtkWidget        *widget,
                        GtkSizeGroupMode  mode)
 {
-  gtk_widget_ensure_style (widget);
-  gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
+  do_size_request (widget);
 
   return get_base_dimension (widget, mode);
 }
@@ -658,9 +670,8 @@ _gtk_size_group_compute_requisition (GtkWidget      *widget,
     }
   else
     {
-      gtk_widget_ensure_style (widget);
-      gtk_signal_emit_by_name (GTK_OBJECT (widget), "size_request", &widget->requisition);
-
+      do_size_request (widget);
+      
       if (requisition)
        get_fast_child_requisition (widget, requisition);
     }
index 86b8edb90c95c78d52b9d11f590bbb8107a43846..18c697f55061382a13529895c2504acffe8a7953 100644 (file)
@@ -452,6 +452,7 @@ static void
 gtk_table_init (GtkTable *table)
 {
   GTK_WIDGET_SET_FLAGS (table, GTK_NO_WINDOW);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (table), FALSE);
   
   table->children = NULL;
   table->rows = NULL;
index 20da6016c2a4d9a8b6843797385806195d97bfe9..6ee796b3941855402dd3656fc20e29e3a02c2498 100644 (file)
@@ -213,6 +213,9 @@ static void         gtk_widget_aux_info_destroy             (GtkWidgetAuxInfo *aux_info);
 static AtkObject*      gtk_widget_real_get_accessible          (GtkWidget        *widget);
 static void            gtk_widget_accessible_interface_init    (AtkImplementorIface *iface);
 static AtkObject*      gtk_widget_ref_accessible               (AtkImplementor *implementor);
+static void             gtk_widget_invalidate_widget_windows    (GtkWidget        *widget,
+                                                                GdkRegion        *region);
+
 
 /* --- variables --- */
 static gpointer         parent_class = NULL;
@@ -1248,6 +1251,8 @@ gtk_widget_init (GtkWidget *widget)
                        (composite_child_stack ? GTK_COMPOSITE_CHILD : 0) |
                        GTK_DOUBLE_BUFFERED);
 
+  GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+
   widget->style = gtk_widget_get_default_style ();
   g_object_ref (widget->style);
 }
@@ -1412,7 +1417,6 @@ gtk_widget_unparent (GtkWidget *widget)
 {
   GObjectNotifyQueue *nqueue;
   GtkWidget *toplevel;
-  GtkWidget *ancestor;
   GtkWidget *old_parent;
   
   g_return_if_fail (GTK_IS_WIDGET (widget));
@@ -1469,64 +1473,6 @@ gtk_widget_unparent (GtkWidget *widget)
   else
     toplevel = NULL;
 
-  if (GTK_IS_RESIZE_CONTAINER (widget))
-    _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
-  
-  /* Remove the widget and all its children from any ->resize_widgets list
-   * of all the parents in our branch. This code should move into gtkcontainer.c
-   * somwhen, since we mess around with ->resize_widgets, which is
-   * actually not of our business.
-   *
-   * Two ways to make this prettier:
-   *   Write a g_slist_conditional_remove (GSList, gboolean (*)(gpointer))
-   *   Change resize_widgets to a GList
-   */
-  ancestor = widget->parent;
-  while (ancestor)
-    {
-      GSList *slist;
-      GSList *prev;
-
-      if (!GTK_CONTAINER (ancestor)->resize_widgets)
-       {
-         ancestor = ancestor->parent;
-         continue;
-       }
-
-      prev = NULL;
-      slist = GTK_CONTAINER (ancestor)->resize_widgets;
-      while (slist)
-       {
-         GtkWidget *child;
-         GtkWidget *parent;
-         GSList *last;
-
-         last = slist;
-         slist = last->next;
-         child = last->data;
-         
-         parent = child;
-         while (parent && (parent != widget))
-           parent = parent->parent;
-         
-         if (parent == widget)
-           {
-             GTK_PRIVATE_UNSET_FLAG (child, GTK_RESIZE_NEEDED);
-             
-             if (prev)
-               prev->next = slist;
-             else
-               GTK_CONTAINER (ancestor)->resize_widgets = slist;
-             
-             g_slist_free_1 (last);
-           }
-         else
-           prev = last;
-       }
-
-      ancestor = ancestor->parent;
-    }
-
   gtk_widget_queue_clear_child (widget);
 
   /* Reset the width and height here, to force reallocation if we
@@ -1831,7 +1777,7 @@ gtk_widget_map (GtkWidget *widget)
       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[MAP]);
 
       if (GTK_WIDGET_NO_WINDOW (widget))
-       gtk_widget_queue_draw (widget);
+       gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
     }
 }
 
@@ -1851,7 +1797,7 @@ gtk_widget_unmap (GtkWidget *widget)
   if (GTK_WIDGET_MAPPED (widget))
     {
       if (GTK_WIDGET_NO_WINDOW (widget))
-       gtk_widget_queue_clear_child (widget);
+       gdk_window_invalidate_rect (widget->window, &widget->allocation, FALSE);
       gtk_signal_emit (GTK_OBJECT (widget), widget_signals[UNMAP]);
     }
 }
@@ -2135,10 +2081,17 @@ gtk_widget_queue_clear (GtkWidget *widget)
 void
 gtk_widget_queue_resize (GtkWidget *widget)
 {
+  GdkRegion *region;
+  
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
-  gtk_widget_queue_clear (widget);
-
+  if (GTK_WIDGET_REALIZED (widget))
+    {
+      region = gdk_region_rectangle (&widget->allocation);
+      gtk_widget_invalidate_widget_windows (widget, region);
+      gdk_region_destroy (region);
+    }
+      
   _gtk_size_group_queue_resize (widget);
 }
 
@@ -2208,13 +2161,6 @@ gtk_widget_size_request (GtkWidget       *widget,
 #endif /* G_ENABLE_DEBUG */
 
   _gtk_size_group_compute_requisition (widget, requisition);
-
-#if 0  
-  if (requisition)
-    gtk_widget_get_child_requisition (widget, requisition);
-
-  gtk_widget_unref (widget);
-#endif  
 }
 
 /**
@@ -2247,6 +2193,38 @@ gtk_widget_get_child_requisition (GtkWidget       *widget,
   _gtk_size_group_get_child_requisition (widget, requisition);
 }
 
+static gboolean
+invalidate_predicate (GdkWindow *window,
+                     gpointer   data)
+{
+  gpointer user_data;
+
+  gdk_window_get_user_data (window, &user_data);
+
+  return (user_data == data);
+}
+
+/* Invalidate @region in widget->window and all children
+ * of widget->window owned by widget. @region is in the
+ * same coordinates as widget->allocation and will be
+ * modified by this call.
+ */
+static void
+gtk_widget_invalidate_widget_windows (GtkWidget *widget,
+                                     GdkRegion *region)
+{
+  if (!GTK_WIDGET_NO_WINDOW (widget))
+    {
+      int x, y;
+      
+      gdk_window_get_position (widget->window, &x, &y);
+      gdk_region_offset (region, -x, -y);
+    }
+
+  gdk_window_invalidate_maybe_recurse (widget->window, region,
+                                      invalidate_predicate, widget);
+}
+
 /**
  * gtk_widget_size_allocate:
  * @widget: a #GtkWidget
@@ -2261,11 +2239,18 @@ gtk_widget_size_allocate (GtkWidget     *widget,
                          GtkAllocation *allocation)
 {
   GtkWidgetAuxInfo *aux_info;
-  GtkAllocation real_allocation;
-  gboolean needs_draw = FALSE;
+  GdkRectangle real_allocation;
+  GdkRectangle old_allocation;
+  gboolean alloc_needed;
+  gboolean size_changed;
+  gboolean position_changed;
   
   g_return_if_fail (GTK_IS_WIDGET (widget));
-  
+
+  alloc_needed = GTK_WIDGET_ALLOC_NEEDED (widget);
+  GTK_PRIVATE_UNSET_FLAG (widget, GTK_ALLOC_NEEDED);
+
+  old_allocation = widget->allocation;
   real_allocation = *allocation;
   aux_info =_gtk_widget_get_aux_info (widget, FALSE);
   
@@ -2287,33 +2272,50 @@ gtk_widget_size_allocate (GtkWidget     *widget,
   real_allocation.width = MAX (real_allocation.width, 1);
   real_allocation.height = MAX (real_allocation.height, 1);
 
-  if (GTK_WIDGET_NO_WINDOW (widget))
+  size_changed = (old_allocation.width != real_allocation.width ||
+                 old_allocation.height != real_allocation.height);
+  position_changed = (old_allocation.x != real_allocation.x ||
+                     old_allocation.y != real_allocation.y);
+
+  if (!alloc_needed && !size_changed && !position_changed)
+    return;
+  
+  gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
+
+  if (GTK_WIDGET_MAPPED (widget))
     {
-      if (widget->allocation.x != real_allocation.x ||
-         widget->allocation.y != real_allocation.y ||
-         widget->allocation.width != real_allocation.width ||
-         widget->allocation.height != real_allocation.height)
+      if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_REDRAW_ON_ALLOC (widget) && position_changed)
        {
-         gtk_widget_queue_clear_child (widget);
-         needs_draw = TRUE;
-       }
-    }
-  else if (widget->allocation.width != real_allocation.width ||
-          widget->allocation.height != real_allocation.height)
-    {
-      needs_draw = TRUE;
-    }
+         /* Invalidate union(old_allaction,widget->allocation) in widget->window
+          */
+         GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
+         gdk_region_union_with_rect (invalidate, &old_allocation);
 
-  if (GTK_IS_RESIZE_CONTAINER (widget))
-    _gtk_container_clear_resize_widgets (GTK_CONTAINER (widget));
+         gdk_window_invalidate_region (widget->window, invalidate, FALSE);
+         gdk_region_destroy (invalidate);
+       }
+      
+      if (size_changed)
+       {
+         if (GTK_WIDGET_REDRAW_ON_ALLOC (widget))
+           {
+             /* Invalidate union(old_allaction,widget->allocation) in widget->window and descendents owned by widget
+              */
+             GdkRegion *invalidate = gdk_region_rectangle (&widget->allocation);
+             gdk_region_union_with_rect (invalidate, &old_allocation);
 
-  gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_ALLOCATE], &real_allocation);
+             gtk_widget_invalidate_widget_windows (widget, invalidate);
+             gdk_region_destroy (invalidate);
+           }
+       }
+    }
 
-  if (needs_draw)
+  if ((size_changed || position_changed) && widget->parent &&
+      GTK_WIDGET_REALIZED (widget->parent) && GTK_CONTAINER (widget->parent)->reallocate_redraws)
     {
-      gtk_widget_queue_draw (widget);
-      if (widget->parent && GTK_CONTAINER (widget->parent)->reallocate_redraws)
-       gtk_widget_queue_draw (widget->parent);
+      GdkRegion *invalidate = gdk_region_rectangle (&widget->parent->allocation);
+      gtk_widget_invalidate_widget_windows (widget->parent, invalidate);
+      gdk_region_destroy (invalidate);
     }
 }
 
@@ -3455,6 +3457,40 @@ gtk_widget_set_double_buffered (GtkWidget *widget,
     GTK_WIDGET_UNSET_FLAGS (widget, GTK_DOUBLE_BUFFERED);
 }
 
+/**
+ * gtk_widget_set_redraw_on_allocate:
+ * @widget: a #GtkWidget
+ * @redraw_on_allocate: if %TRUE, the entire widget will be redrawn
+ *   when it is allocated to a new size. Otherwise, only the
+ *   new portion of the widget will be redrawn.
+ *
+ * Sets whether a when a widgets size allocation changes, the entire
+ * widget is queued for drawing. By default, this setting is %TRUE and
+ * the entire widget is redrawn on every size change. If your widget
+ * leaves the upper left are unchanged when made bigger, turning this
+ * setting on will improve performance.
+
+ * Note that for NO_WINDOW widgets setting this flag to %FALSE turns
+ * off all allocation on resizing: the widget will not even redraw if
+ * its position changes; this is to allow containers that don't draw
+ * anything to avoid excess invalidations. If you set this flag on a
+ * NO_WINDOW widget that _does_ draw on widget->window, you are
+ * responsible for invalidating both the old and new allocation of the
+ * widget when the widget is moved and responsible for invalidating
+ * regions newly when the widget increases size.
+ **/
+void
+gtk_widget_set_redraw_on_allocate (GtkWidget *widget,
+                                  gboolean   redraw_on_allocate)
+{
+  g_return_if_fail (GTK_IS_WIDGET (widget));
+
+  if (redraw_on_allocate)
+    GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+  else
+    GTK_PRIVATE_UNSET_FLAG (widget, GTK_REDRAW_ON_ALLOC);
+}
+
 /**
  * gtk_widget_set_sensitive:
  * @widget: a @widget
index 111c7792689b38bf810c824901b1d28ea19ebd8b..3d9969a249235f1dd759cbbb90c596aeca2f0fff 100644 (file)
@@ -539,25 +539,27 @@ gboolean   gtk_widget_is_focus            (GtkWidget           *widget);
 void      gtk_widget_grab_focus          (GtkWidget           *widget);
 void      gtk_widget_grab_default        (GtkWidget           *widget);
 
-void      gtk_widget_set_name            (GtkWidget           *widget,
-                                          const gchar         *name);
-G_CONST_RETURN gchar* gtk_widget_get_name (GtkWidget          *widget);
-void      gtk_widget_set_state           (GtkWidget           *widget,
-                                          GtkStateType         state);
-void      gtk_widget_set_sensitive       (GtkWidget           *widget,
-                                          gboolean             sensitive);
-void      gtk_widget_set_app_paintable   (GtkWidget           *widget,
-                                          gboolean             app_paintable);
-void      gtk_widget_set_double_buffered (GtkWidget           *widget,
-                                          gboolean             double_buffered);
-void      gtk_widget_set_parent          (GtkWidget           *widget,
-                                          GtkWidget           *parent);
-void      gtk_widget_set_parent_window   (GtkWidget           *widget,
-                                          GdkWindow           *parent_window);
-void       gtk_widget_set_child_visible   (GtkWidget           *widget,
-                                          gboolean             is_visible);
-gboolean   gtk_widget_get_child_visible   (GtkWidget           *widget);
-     
+void                  gtk_widget_set_name               (GtkWidget    *widget,
+                                                        const gchar  *name);
+G_CONST_RETURN gchar* gtk_widget_get_name               (GtkWidget    *widget);
+void                  gtk_widget_set_state              (GtkWidget    *widget,
+                                                        GtkStateType  state);
+void                  gtk_widget_set_sensitive          (GtkWidget    *widget,
+                                                        gboolean      sensitive);
+void                  gtk_widget_set_app_paintable      (GtkWidget    *widget,
+                                                        gboolean      app_paintable);
+void                  gtk_widget_set_double_buffered    (GtkWidget    *widget,
+                                                        gboolean      double_buffered);
+void                  gtk_widget_set_redraw_on_allocate (GtkWidget    *widget,
+                                                        gboolean      redraw_on_allocate);
+void                  gtk_widget_set_parent             (GtkWidget    *widget,
+                                                        GtkWidget    *parent);
+void                  gtk_widget_set_parent_window      (GtkWidget    *widget,
+                                                        GdkWindow    *parent_window);
+void                  gtk_widget_set_child_visible      (GtkWidget    *widget,
+                                                        gboolean      is_visible);
+gboolean              gtk_widget_get_child_visible      (GtkWidget    *widget);
+
 GtkWidget *gtk_widget_get_parent          (GtkWidget           *widget);
 GdkWindow *gtk_widget_get_parent_window          (GtkWidget           *widget);
 gboolean   gtk_widget_child_focus         (GtkWidget           *widget,
index 6bedb3aabe5d4eb0a05f20ec528e4fdc2543fb0f..412a57f891aefa7fda53e91cc0e08d83c753a91f 100644 (file)
@@ -3366,7 +3366,7 @@ gtk_window_configure_event (GtkWidget         *widget,
   widget->allocation.width = event->width;
   widget->allocation.height = event->height;
   
-  gtk_widget_queue_resize (widget);
+  _gtk_container_queue_resize (GTK_CONTAINER (widget));
   
   return TRUE;
 }
@@ -4144,7 +4144,6 @@ gtk_window_move_resize (GtkWindow *window)
       /* gtk_window_configure_event() filled in widget->allocation */
       allocation = widget->allocation;
       gtk_widget_size_allocate (widget, &allocation);
-      gtk_widget_queue_draw (widget);
 
       /* If the configure request changed, it means that
        * we either:
@@ -4284,8 +4283,7 @@ gtk_window_move_resize (GtkWindow *window)
       
       /* And run the resize queue.
        */
-      if (container->resize_widgets)
-        gtk_container_resize_children (container);
+      gtk_container_resize_children (container);
     }
 }